using Daemon.Common.Const;
using Daemon.Common.Extensions;
using Daemon.Common.Generator;
using JinianNet.JNTemplate;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daemon.Common.Generator
{
	public static class GeneratorHelper
	{
		/// <summary>
		/// generate front entity or backend entity code
		/// </summary>
		/// <param name="request"></param>
		/// <param name="templateFilePath"></param>
		/// <param name="generateFilePath"></param>
		/// <param name="isGenerateFile"></param>
		/// <returns></returns>
		public static string GenerateEntityCode(GeneratorRequest request, string templateFilePath, string generateFilePath = "", bool isFrontCode = false, bool isGenerateFile = false)
		{
			Engine.Configure(c =>
				{
					c.TagPrefix = "${";
					c.TagSuffix = "}";
					c.TagFlag = '$';
				});
			var codeInfo = new EntityGenerateDTO() { ClassName = request.Name, ClassComment = request.TableInfo.TableComment };
			var rootPathDir = System.IO.Path.GetFullPath("../");
			List<FieldDto> fieldDTOList = new List<FieldDto>();
			foreach (var columnInfo in request.TableInfo.ColumnInfos)
			{
				var typeScriptDto = new FieldDto() { };
				typeScriptDto.FieldComment = columnInfo.FieldComment;
				typeScriptDto.FieldName = columnInfo.FieldName;
				FieldType fieldType = FieldTypeConst.GetByValue(columnInfo.FieldType);
				if (fieldType == null)
				{
					fieldType = FieldTypeConst.GetFieldTypeList().Find(r => r.Key == "TEXT");
				}

				typeScriptDto.FieldType = isFrontCode ? fieldType.TypeScriptType : fieldType.CSharpType;
				fieldDTOList.Add(typeScriptDto);
			}

			codeInfo.FieldDto = fieldDTOList;
			var entityTemplate = Engine.LoadTemplate(templateFilePath);
			entityTemplate.Set("primaryKey", request.TableInfo.PrimaryKey);
			entityTemplate.Set("modelName", request.Name);
			entityTemplate.Set("entity", codeInfo);
			if (!request.IsFrontCode)
			{
				entityTemplate.Set("tableName", request.TableInfo.TableName);
			}
			var result = entityTemplate.Render();
			if (isGenerateFile)
			{
				try
				{
					Daemon.Common.DirFile.CreateFile($@"{generateFilePath}\\{request.Name}{request.Extension}", result);
				}
				catch (Exception)
				{
					return "";
				}
			}

			return result;
		}

		/// <summary>
		/// generate code
		/// </summary>
		/// <param name="request"></param>
		/// <param name="templateFilePath"></param>
		/// <param name="generateFilePath"></param>
		/// <param name="isGenerateFile"></param>
		public static string CommonGenerateBackEndCode(GeneratorRequest request, string templateFilePath, string generateFilePath = "", bool isGenerateFile = false)
		{
			if (request.IsFrontCode)
			{
				Engine.Configure(c =>
				{
					c.TagPrefix = "@{";
					c.TagSuffix = "}";
				});
			}
			else
			{
				Engine.Configure(c =>
				{
					c.TagPrefix = "${";
					c.TagSuffix = "}";
				});
			}
			var templateFile = Engine.LoadTemplate(templateFilePath);
			templateFile.Set("modelName", request.Name);
			templateFile.Set("apiRoute", request.Name.CapitalizeLower());
			templateFile.Set("repositoryName", request.Name.CapitalizeLower());
			var result = templateFile.Render();
			if (isGenerateFile)
			{
				Daemon.Common.DirFile.CreateFile($@"{generateFilePath}\\{request.GenerateFileName}{request.Extension}", result);
			}

			return result;
		}

		public static string GenerateFrontTableIndex(GeneratorRequest request, string templateFilePath, string generateFilePath = "", bool isGenerateFile = false)
		{
			var result = string.Empty;
			Engine.Configure(c =>
			{
				c.TagPrefix = "@{";
				c.TagSuffix = "}";
			});
			var codeInfo = new EntityGenerateDTO() { ClassName = request.Name, ClassComment = request.TableInfo.TableComment };
			List<FieldDto> fieldDTOList = new List<FieldDto>();
			foreach (var columnInfo in request.TableInfo.ColumnInfos)
			{
				var typeScriptDto = new FieldDto() { };
				typeScriptDto.FieldComment = columnInfo.FieldComment;
				typeScriptDto.FieldName = columnInfo.FieldName;
				FieldType fieldType = FieldTypeConst.GetByValue(columnInfo.FieldType);
				if (fieldType == null)
				{
					fieldType = FieldTypeConst.GetFieldTypeList().Find(r => r.Key == "TEXT");
				}

				typeScriptDto.FieldType = fieldType.TypeScriptType;
				fieldDTOList.Add(typeScriptDto);
			}

			codeInfo.FieldDto = fieldDTOList;
			var templateFile = Engine.LoadTemplate(templateFilePath);
			templateFile.Set("entity", codeInfo);
			templateFile.Set("modelName", request.Name);
			templateFile.Set("serviceName", request.Name.CapitalizeLower());
			templateFile.Set("primaryKey", request.TableInfo.PrimaryKey);
			templateFile.Set("tableComment", request.TableInfo.TableComment);
			result = templateFile.Render();
			if (isGenerateFile)
			{
				Daemon.Common.DirFile.CreateFile($@"{generateFilePath}\\{request.GenerateFileName}{request.Extension}", result);
			}

			return result;
		}

		public static string GenerateForm(string templateFilePath, List<Component> components, List<string> componentsHtml, List<string> variableList)
		{
			var result = string.Empty;
			Engine.Configure(c =>
			{
				c.TagPrefix = "@{";
				c.TagSuffix = "}";
			});
			var templateFile = Engine.LoadTemplate(templateFilePath);
			templateFile.Set("components", components);
			templateFile.Set("variableList", variableList);
			templateFile.Set("componentHtmlList", componentsHtml);
			templateFile.Set("antComponentName", string.Join(',', components.Where(r => r.Widget != WidgetTypeEnum.UploadImg).Select(r => r.Widget).Distinct()));
			result = templateFile.Render();
			return result;
		}


	}

	public class CodeInfo
	{
		public string FrontEntity { get; set; }

		public string FrontService { get; set; }

		public string BackEntity { get; set; }

		public string Controller { get; set; }

		public string BackEndService { get; set; }

		public string BackEndIService { get; set; }

		public string BackEndRepository { get; set; }

		public string BackEndIRepository { get; set; }
	}
}